/*
 * 1. AT command and log: UART3
 * 2. HCI interface: UART0, GPIO_PMU, handled by host.c.
 * 3. Display: DMA1, SPIx8_0, GPIO (for cs)
 * 4. Touchpad: I2C3
 * 5. PSRAM: OSPI
 * 6. external Flash: DMA0, SPIx8_1
 * 7. DSP: IPC, RPMSG
 * 8. DSP XIP Flash: QSPI1
 * 9. Sensors: handled by 1010
 * 10. System clock, XIP Flash: handled by sleep procedure
 */
 
#include "fr30xx.h"

#include "driver_display.h"
//#include "driver_touchpad.h"
//#include "driver_psram.h"
#include "IC_W25Qxx.h"

#include "app_config.h"
#include "app_hw.h"

#define PSRAM_EXT_IO_CONTROLE

struct hw_gpio_state_t {
    uint16_t PortA_PullEN;
    uint16_t PortB_PullEN;
    uint16_t PortC_PullEN;
    uint16_t PortD_PullEN;
    
    uint16_t PortA_PullSelect;
    uint16_t PortB_PullSelect;
    uint16_t PortC_PullSelect;
    uint16_t PortD_PullSelect;
    
    uint32_t PortA_PullResCfg;
    uint32_t PortB_PullResCfg;
    uint32_t PortC_PullResCfg;
    uint32_t PortD_PullResCfg;
    
    uint32_t PortA_DriveCfg;
    uint32_t PortB_DriveCfg;
    uint32_t PortC_DriveCfg;
    uint32_t PortD_DriveCfg;
    
    uint32_t PortA_L_FuncMux;
    uint32_t PortA_H_FuncMux;
    uint32_t PortB_L_FuncMux;
    uint32_t PortB_H_FuncMux;
    uint32_t PortC_L_FuncMux;
    uint32_t PortC_H_FuncMux;
    uint32_t PortD_L_FuncMux;
    uint32_t PortD_H_FuncMux;
    
    uint32_t QSPI_PullSelect;
    uint32_t QSPI_PullEN;
    uint32_t OSPI_PullSelect;
    uint32_t OSPI_PullEN;
    
    uint16_t GPIOA_OutputEN;
    uint16_t GPIOA_OUT_DATA;
    uint16_t GPIOA_EXTI_EN;
    uint16_t GPIOA_EXTI_INT_EN;
    uint32_t GPIOA_EXTI_TYPE;
    uint16_t GPIOB_OutputEN;
    uint16_t GPIOB_OUT_DATA;
    uint16_t GPIOB_EXTI_EN;
    uint16_t GPIOB_EXTI_INT_EN;
    uint32_t GPIOB_EXTI_TYPE;
    uint16_t GPIOC_OutputEN;
    uint16_t GPIOC_OUT_DATA;
    uint16_t GPIOC_EXTI_EN;
    uint16_t GPIOC_EXTI_INT_EN;
    uint32_t GPIOC_EXTI_TYPE;
    uint16_t GPIOD_OutputEN;
    uint16_t GPIOD_OUT_DATA;
    uint16_t GPIOD_EXTI_EN;
    uint16_t GPIOD_EXTI_INT_EN;
    uint32_t GPIOD_EXTI_TYPE;
};

static struct hw_gpio_state_t gpio_state;

UART_HandleTypeDef uart_log_handle;
DMA_HandleTypeDef dma_display_handle;
SPI_HandleTypeDef spi_display_handle;
I2C_HandleTypeDef i2c_touchpad_handle;
SPI_HandleTypeDef spi_flash_handle;
DMA_HandleTypeDef dma_flash_handle;

void app_at_rx_done(struct __UART_HandleTypeDef *handle);

void display_cs_set(void)
{
    gpio_write_pin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
}

void display_cs_clear(void)
{
    gpio_write_pin(GPIOC, GPIO_PIN_5, GPIO_PIN_CLEAR);
}

#if BOARD_SEL == BOARD_EVB_FR5090
void display_reset_set(void)
{
    gpio_write_pin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);
}

void display_reset_clear(void)
{
    gpio_write_pin(GPIOB, GPIO_PIN_14, GPIO_PIN_CLEAR);
}

void display_vci_set(void)
{
    gpio_write_pin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET);
}

void display_vci_clear(void)
{
    gpio_write_pin(GPIOB, GPIO_PIN_13, GPIO_PIN_CLEAR);
}

bool display_te_status(void)
{
    return 1;
}
#elif BOARD_SEL == BOARD_EVB_FR3092E
void display_reset_set(void)
{
    gpio_write_pin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
}

void display_reset_clear(void)
{
    gpio_write_pin(GPIOC, GPIO_PIN_6, GPIO_PIN_CLEAR);
}

void display_vci_set(void)
{
    gpio_write_pin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
}

void display_vci_clear(void)
{
    gpio_write_pin(GPIOC, GPIO_PIN_15, GPIO_PIN_CLEAR);
}

bool display_te_status(void)
{
    return gpio_read_pin(GPIOC, GPIO_PIN_7);
}
#elif BOARD_SEL == BOARD_EVB_FR3092E_CM
void display_reset_set(void)
{
    gpio_write_pin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);
}

void display_reset_clear(void)
{
    gpio_write_pin(GPIOB, GPIO_PIN_14, GPIO_PIN_CLEAR);
}

void display_vci_set(void)
{
    gpio_write_pin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET);
}

void display_vci_clear(void)
{
    gpio_write_pin(GPIOB, GPIO_PIN_13, GPIO_PIN_CLEAR);
}

bool display_te_status(void)
{
    return gpio_read_pin(GPIOB, GPIO_PIN_15);
}
#elif BOARD_SEL == BOARD_EVB_FR3092E
void display_reset_set(void)
{
    gpio_write_pin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
}

void display_reset_clear(void)
{
    gpio_write_pin(GPIOC, GPIO_PIN_6, GPIO_PIN_CLEAR);
}

void display_vci_set(void)
{
    gpio_write_pin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
}

void display_vci_clear(void)
{
    gpio_write_pin(GPIOC, GPIO_PIN_15, GPIO_PIN_CLEAR);
}

bool display_te_status(void)
{
    return gpio_read_pin(GPIOC, GPIO_PIN_7);
}
#elif BOARD_SEL == BOARD_EVB_FR3092E_RGB
void display_reset_set(void)
{
    gpio_write_pin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);
}

void display_reset_clear(void)
{
    gpio_write_pin(GPIOB, GPIO_PIN_14, GPIO_PIN_CLEAR);
}

void display_vci_set(void)
{
    gpio_write_pin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET);
}

void display_vci_clear(void)
{
    gpio_write_pin(GPIOB, GPIO_PIN_13, GPIO_PIN_CLEAR);
}

bool display_te_status(void)
{
    return gpio_read_pin(GPIOB, GPIO_PIN_15);
}
#else
#error "choose correct board"
#endif

void display_delay_ms(uint32_t counter)
{
    system_delay_us(counter * 1000);
}

#if BOARD_SEL == BOARD_EVB_FR5090
void touchpad_reset_set(void)
{
    gpio_write_pin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
}

void touchpad_reset_clear(void)
{
    gpio_write_pin(GPIOC, GPIO_PIN_15, GPIO_PIN_CLEAR);
}
#elif BOARD_SEL == BOARD_EVB_FR3092E

    #if 1       //DISPLAY_TYPE_ICNA3310
    void touchpad_reset_set(void)
    {
        gpio_write_pin(GPIOB, GPIO_PIN_15, GPIO_PIN_SET);
    }

    void touchpad_reset_clear(void)
    {
        gpio_write_pin(GPIOB, GPIO_PIN_15, GPIO_PIN_CLEAR);
    }
    #else
    void touchpad_reset_set(void)
    {
        gpio_write_pin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET);
    }

    void touchpad_reset_clear(void)
    {
        gpio_write_pin(GPIOA, GPIO_PIN_6, GPIO_PIN_CLEAR);
    }
    #endif

#elif BOARD_SEL == BOARD_EVB_FR3092E_CM
void touchpad_reset_set(void)
{
    gpio_write_pin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
}

void touchpad_reset_clear(void)
{
    gpio_write_pin(GPIOC, GPIO_PIN_15, GPIO_PIN_CLEAR);
}
#elif BOARD_SEL == BOARD_EVB_FR3092E_RGB
void touchpad_reset_set(void)
{
    gpio_write_pin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
}

void touchpad_reset_clear(void)
{
    gpio_write_pin(GPIOD, GPIO_PIN_14, GPIO_PIN_CLEAR);
}
#else
#error "choose correct board"
#endif

void touchpad_delay_ms(uint32_t counter)
{
    system_delay_us(counter * 1000);
}

__RAM_CODE void hw_log_init(bool wake_up)
{

    #if 1

    if (wake_up == false) {
        GPIO_InitTypeDef gpio_config;

        /* ========================================================== */
        /* =========         Uart LOG configuration         ========= */
        /* ========================================================== */
        /* configure PB4 and PB5 to UART3 function */
        gpio_config.Pin = GPIO_PIN_4 | GPIO_PIN_5;
        gpio_config.Mode = GPIO_MODE_AF_PP;
        gpio_config.Pull = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_1;
        gpio_init(GPIOB, &gpio_config);

        __SYSTEM_UART3_CLK_ENABLE();
        
        /* UART3: used for Log and AT command */
        uart_log_handle.UARTx = UART3;
        uart_log_handle.Init.BaudRate   = 921600;
        uart_log_handle.Init.DataLength = UART_DATA_LENGTH_8BIT;
        uart_log_handle.Init.StopBits   = UART_STOPBITS_1;
        uart_log_handle.Init.Parity     = UART_PARITY_NONE;
        uart_log_handle.Init.FIFO_Mode  = UART_FIFO_ENABLE;
        uart_log_handle.TxCpltCallback  = NULL;
        uart_log_handle.RxCpltCallback  = app_at_rx_done;
        uart_init(&uart_log_handle);
        NVIC_EnableIRQ(UART3_IRQn);
    }
    else {
        __SYSTEM_UART3_CLK_ENABLE();
        uart_init(&uart_log_handle);
        __UART_INT_RX_ENABLE(uart_log_handle.UARTx);
        NVIC_EnableIRQ(UART3_IRQn);
    }

    #else

    if (wake_up == false) {
        GPIO_InitTypeDef gpio_config;

        /* ========================================================== */
        /* =========         Uart LOG configuration         ========= */
        /* ========================================================== */
        /* configure PC0 and PC1 to UART2 function */
        gpio_config.Pin = GPIO_PIN_12 | GPIO_PIN_13;
        gpio_config.Mode = GPIO_MODE_AF_PP;
        gpio_config.Pull = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_1;
        gpio_init(GPIOD, &gpio_config);

        __SYSTEM_UART5_CLK_ENABLE();
        
        /* UART2: used for Log and AT command */
        uart_log_handle.UARTx = UART5;
        uart_log_handle.Init.BaudRate   = 921600;
        uart_log_handle.Init.DataLength = UART_DATA_LENGTH_8BIT;
        uart_log_handle.Init.StopBits   = UART_STOPBITS_1;
        uart_log_handle.Init.Parity     = UART_PARITY_NONE;
        uart_log_handle.Init.FIFO_Mode  = UART_FIFO_ENABLE;
        uart_log_handle.TxCpltCallback  = NULL;
        uart_log_handle.RxCpltCallback  = app_at_rx_done;
        uart_init(&uart_log_handle);
        NVIC_EnableIRQ(UART5_IRQn);
    }
    else {
        __SYSTEM_UART2_CLK_ENABLE();
        uart_init(&uart_log_handle);
        __UART_INT_RX_ENABLE(uart_log_handle.UARTx);
        NVIC_EnableIRQ(UART5_IRQn);
    }

    #endif
}

#if 0
__RAM_CODE void hw_display_init(bool wake_up)
{
    if (wake_up == false) {
        GPIO_InitTypeDef gpio_config;

        /* ========================================================== */
        /* =========    Display interface configuration     ========= */
        /* ========================================================== */
        /* config DMA1 for display */
        __SYSTEM_DMA0_CLK_ENABLE();
        dma_display_handle.DMAx                       = DMA0;
        dma_display_handle.Channel                    = DMA_Channel1;
        dma_display_handle.Init.Data_Flow             = DMA_M2P_DMAC;
        dma_display_handle.Init.Request_ID            = 2;
        system_dmac_request_id_config(SPIMX8_0_TX, DMA0_REQUEST_ID_2);
        dma_display_handle.Init.Source_Master_Sel     = DMA_AHB_MASTER_2;
        dma_display_handle.Init.Desination_Master_Sel = DMA_AHB_MASTER_3;
        dma_display_handle.Init.Source_Inc            = DMA_ADDR_INC_INC;
        dma_display_handle.Init.Desination_Inc        = DMA_ADDR_INC_NO_CHANGE;
        dma_display_handle.Init.Source_Width          = DMA_TRANSFER_WIDTH_16;
        dma_display_handle.Init.Desination_Width      = DMA_TRANSFER_WIDTH_16;
        dma_display_handle.Init.Source_Burst_Len      = DMA_BURST_LEN_32;
        dma_display_handle.Init.Desination_Burst_Len  = DMA_BURST_LEN_32;
        dma_init(&dma_display_handle);

        NVIC_ClearPendingIRQ(DMA0_IRQn);
        NVIC_EnableIRQ(DMA0_IRQn);

        __SYSTEM_GPIOB_CLK_ENABLE();
        __SYSTEM_GPIOC_CLK_ENABLE();

        /* configure C0, C1, C2, C3, C4 to SPIx8_0 function */
        gpio_config.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4;
        gpio_config.Mode = GPIO_MODE_AF_PP;
        gpio_config.Pull = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_5;
        gpio_init(GPIOC, &gpio_config);

        /* configure C5 to CS function */
        gpio_config.Pin = GPIO_PIN_5;
        gpio_config.Mode = GPIO_MODE_OUTPUT_PP;
        gpio_config.Pull = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_init(GPIOC, &gpio_config);

#if BOARD_SEL == BOARD_EVB_FR5090
        /* configure B13, PB14 to VCCI function, RESET function */
        gpio_config.Pin = GPIO_PIN_13 | GPIO_PIN_14;
        gpio_config.Mode = GPIO_MODE_OUTPUT_PP;
        gpio_config.Pull = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_init(GPIOB, &gpio_config);
#elif BOARD_SEL == BOARD_EVB_FR3092E
        /* configure PC15, PC6 to VCCI function, RESET function n*/
        gpio_config.Pin = GPIO_PIN_6 | GPIO_PIN_15;
        gpio_config.Mode = GPIO_MODE_OUTPUT_PP;
        gpio_config.Pull = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_init(GPIOC, &gpio_config);

        /* configure GPIO_PC7 to TE functio(interrupt pin)  */
        gpio_config.Pin       = GPIO_PIN_7;
        gpio_config.Mode      = GPIO_MODE_INPUT;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_config.Pull      = GPIO_PULLDOWN;
        gpio_init(GPIOC, &gpio_config);
#elif BOARD_SEL == BOARD_EVB_FR3092E_CM
        /* configure B13, PB14 to VCCI function, RESET function */
        gpio_config.Pin = GPIO_PIN_13 | GPIO_PIN_14;
        gpio_config.Mode = GPIO_MODE_OUTPUT_PP;
        gpio_config.Pull = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_init(GPIOB, &gpio_config);

        /* configure GPIO_PB15 to TE functio(interrupt pin)  */
        gpio_config.Pin       = GPIO_PIN_15;
        gpio_config.Mode      = GPIO_MODE_INPUT;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_config.Pull      = GPIO_PULLDOWN;
        gpio_init(GPIOB, &gpio_config);
#elif BOARD_SEL == BOARD_EVB_FR3092E_RGB
        /* configure PC15, PC6 to VCCI function, RESET function n*/
        gpio_config.Pin = GPIO_PIN_6 | GPIO_PIN_15;
        gpio_config.Mode = GPIO_MODE_OUTPUT_PP;
        gpio_config.Pull = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_init(GPIOC, &gpio_config);

        /* configure GPIO_PC7 to TE functio(interrupt pin)  */
        gpio_config.Pin       = GPIO_PIN_7;
        gpio_config.Mode      = GPIO_MODE_INPUT;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_config.Pull      = GPIO_PULLDOWN;
        gpio_init(GPIOC, &gpio_config);
#else
        #error "choose correct board"
#endif

        __SYSTEM_SPI_MASTER0_X8_CLK_ENABLE();
        spi_display_handle.SPIx                       = SPIMX8_0;
        spi_display_handle.Init.Work_Mode             = SPI_WORK_MODE_0;
        spi_display_handle.Init.Frame_Size            = SPI_FRAME_SIZE_8BIT;
#if BOARD_SEL == BOARD_EVB_FR5090
        spi_display_handle.Init.BaudRate_Prescaler    = 2;
#elif BOARD_SEL == BOARD_EVB_FR3092E
        spi_display_handle.Init.BaudRate_Prescaler    = 4;
#elif BOARD_SEL == BOARD_EVB_FR3092E_CM
        spi_display_handle.Init.BaudRate_Prescaler    = 4;
#elif BOARD_SEL == BOARD_EVB_FR3092E_RGB
        spi_display_handle.Init.BaudRate_Prescaler    = 4;		
 #else
        #error "choose correct board"
 #endif
        spi_display_handle.Init.TxFIFOEmpty_Threshold = 20;
        spi_display_handle.Init.RxFIFOFull_Threshold  = 0;
        spi_master_init(&spi_display_handle);
        
        display_cs_set();
        display_init();
    }
    else {
        __SYSTEM_DMA0_CLK_ENABLE();
        system_dmac_request_id_config(SPIMX8_0_TX, DMA0_REQUEST_ID_2);
        dma_init(&dma_display_handle);
        NVIC_ClearPendingIRQ(DMA0_IRQn);
        NVIC_EnableIRQ(DMA0_IRQn);
        
        __SYSTEM_GPIOB_CLK_ENABLE();
        __SYSTEM_GPIOC_CLK_ENABLE();
        __SYSTEM_SPI_MASTER0_X8_CLK_ENABLE();
        spi_display_handle.Init.Frame_Size = SPI_FRAME_SIZE_8BIT;
        spi_master_init(&spi_display_handle);
    }
}
#endif

#if 0
__RAM_CODE void hw_touchpad_init(bool wake_up)
{
    if (wake_up == false) {
        GPIO_InitTypeDef gpio_config;

        /* ========================================================== */
        /* =========            TP configuration            ========= */
        /* ========================================================== */
        __SYSTEM_GPIOC_CLK_ENABLE();

#if BOARD_SEL == BOARD_EVB_FR5090
        /* configure GPIO_PC6 and GPIO_PC7 to I2C3 mode */
        gpio_config.Pin       = GPIO_PIN_6|GPIO_PIN_7;
        gpio_config.Mode      = GPIO_MODE_AF_PP;
        gpio_config.Pull      = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_3;
        gpio_init(GPIOC, &gpio_config);

        /* configure GPIO_PC15 to reset pin */
        gpio_config.Pin       = GPIO_PIN_15;
        gpio_config.Mode      = GPIO_MODE_OUTPUT_PP;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_init(GPIOC, &gpio_config);

        /* configure GPIO_PC14 to interrupt pin */
        gpio_config.Pin       = GPIO_PIN_14;
        gpio_config.Mode      = GPIO_MODE_EXTI_IT_FALLING;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_config.Pull      = GPIO_PULLUP;
        gpio_init(GPIOC, &gpio_config);
#elif BOARD_SEL == BOARD_EVB_FR3092E

        #if 1       //DISPLAY_TYPE_ICNA3310
        /* configure GPIO_PB12 and GPIO_PB13 to I2C2 mode */
        gpio_config.Pin       = GPIO_PIN_12|GPIO_PIN_13;
        gpio_config.Mode      = GPIO_MODE_AF_PP;
        gpio_config.Pull      = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_3;
        gpio_init(GPIOB, &gpio_config);

        /* configure GPIO_PB15 to reset pin */
        gpio_config.Pin       = GPIO_PIN_15;
        gpio_config.Mode      = GPIO_MODE_OUTPUT_PP;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_init(GPIOB, &gpio_config);

        /* configure GPIO_PB14 to interrupt pin */
        gpio_config.Pin       = GPIO_PIN_14;
        gpio_config.Mode      = GPIO_MODE_EXTI_IT_FALLING;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_config.Pull      = GPIO_PULLUP;
        gpio_init(GPIOB, &gpio_config);


        exti_interrupt_enable(GPIOB,EXTI_LINE_14);
        exti_clear_LineStatus(GPIOB,EXTI_LINE_14);
        
        NVIC_EnableIRQ(GPIOB_IRQn);

        #else

        /* configure GPIO_PA4 and GPIO_PA5 to I2C2 mode */
        gpio_config.Pin       = GPIO_PIN_4|GPIO_PIN_5;
        gpio_config.Mode      = GPIO_MODE_AF_PP;
        gpio_config.Pull      = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_3;
        gpio_init(GPIOA, &gpio_config);

        __SYSTEM_GPIOA_CLK_ENABLE();
        /* configure GPIO_PA6 to reset pin */
        gpio_config.Pin       = GPIO_PIN_6;
        gpio_config.Mode      = GPIO_MODE_OUTPUT_PP;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_init(GPIOA, &gpio_config);
        
        __SYSTEM_GPIOB_CLK_ENABLE();
        /* configure GPIO_PB14 to interrupt pin */
        gpio_config.Pin       = GPIO_PIN_14;
        gpio_config.Mode      = GPIO_MODE_EXTI_IT_FALLING;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_config.Pull      = GPIO_PULLUP;
        gpio_init(GPIOB, &gpio_config);

        #endif
#elif BOARD_SEL == BOARD_EVB_FR3092E_CM
        /* configure GPIO_PC6 and GPIO_PC7 to I2C3 mode */
        gpio_config.Pin       = GPIO_PIN_6|GPIO_PIN_7;
        gpio_config.Mode      = GPIO_MODE_AF_PP;
        gpio_config.Pull      = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_3;
        gpio_init(GPIOC, &gpio_config);

        /* configure GPIO_PC15 to reset pin */
        gpio_config.Pin       = GPIO_PIN_15;
        gpio_config.Mode      = GPIO_MODE_OUTPUT_PP;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_init(GPIOC, &gpio_config);

        /* configure GPIO_PC14 to interrupt pin */
        gpio_config.Pin       = GPIO_PIN_14;
        gpio_config.Mode      = GPIO_MODE_EXTI_IT_FALLING;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_config.Pull      = GPIO_PULLUP;
        gpio_init(GPIOC, &gpio_config);
#elif BOARD_SEL == BOARD_EVB_FR3092E_RGB
		__SYSTEM_GPIOA_CLK_ENABLE();
		__SYSTEM_GPIOD_CLK_ENABLE();
		 
		gpio_config.Pin       = GPIO_PIN_10|GPIO_PIN_11;
        gpio_config.Mode      = GPIO_MODE_OUTPUT_PP;
        gpio_config.Pull      = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_init(GPIOA, &gpio_config);

	    gpio_config.Pin       = GPIO_PIN_14;
        gpio_config.Mode      = GPIO_MODE_OUTPUT_PP;
        gpio_config.Pull      = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_init(GPIOD, &gpio_config);
		gpio_write_pin(GPIOD, GPIO_PIN_14, GPIO_PIN_CLEAR);	
		
		gpio_config.Pin       = GPIO_PIN_7;
        gpio_config.Mode      = GPIO_MODE_OUTPUT_PP;
        gpio_config.Pull      = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_init(GPIOD, &gpio_config);
		gpio_write_pin(GPIOD, GPIO_PIN_7, GPIO_PIN_CLEAR);

		// exti_interrupt_enable(GPIOB,EXTI_LINE_11);
        // exti_clear_LineStatus(GPIOB,EXTI_LINE_11);
        // NVIC_EnableIRQ(GPIOB_IRQn);

#else
    #error "choose correct board"
#endif

        /* I2C Init */
#if BOARD_SEL == BOARD_EVB_FR5090
        __SYSTEM_I2C3_CLK_ENABLE();
        i2c_touchpad_handle.I2Cx = I2C3;
        i2c_touchpad_handle.Init.I2C_Mode = I2C_MODE_MASTER_7BIT;
        i2c_touchpad_handle.Init.SCL_HCNT = 220;
        i2c_touchpad_handle.Init.SCL_LCNT = 230;
#elif BOARD_SEL == BOARD_EVB_FR3092E
        __SYSTEM_I2C2_CLK_ENABLE();
        i2c_touchpad_handle.I2Cx = I2C2;
        i2c_touchpad_handle.Init.I2C_Mode = I2C_MODE_MASTER_7BIT;
        i2c_touchpad_handle.Init.SCL_HCNT = 220;
        i2c_touchpad_handle.Init.SCL_LCNT = 230;
#elif BOARD_SEL == BOARD_EVB_FR3092E_CM
        __SYSTEM_I2C3_CLK_ENABLE();
        i2c_touchpad_handle.I2Cx = I2C3;
        i2c_touchpad_handle.Init.I2C_Mode = I2C_MODE_MASTER_7BIT;
        i2c_touchpad_handle.Init.SCL_HCNT = 90;
        i2c_touchpad_handle.Init.SCL_LCNT = 90;
#elif BOARD_SEL == BOARD_EVB_FR3092E_RGB

		// __SYSTEM_I2C2_CLK_ENABLE();
        // i2c_touchpad_handle.I2Cx = I2C2;
        // i2c_touchpad_handle.Init.I2C_Mode = I2C_MODE_MASTER_7BIT;
		// i2c_touchpad_handle.Init.SCL_HCNT = 220;
        // i2c_touchpad_handle.Init.SCL_LCNT = 230;	
	
#else

    #error "choose correct board"
#endif
        __TOUCHPAD_RESET_SET();
        touchpad_init();
		//i2c_init(&i2c_touchpad_handle);
    }
    else {
//        __SYSTEM_GPIOC_CLK_ENABLE();
//#if BOARD_SEL == BOARD_EVB_FR3092E
//        __SYSTEM_I2C2_CLK_ENABLE();
//#elif BOARD_SEL == BOARD_EVB_FR3092E_RGB
//		__SYSTEM_I2C2_CLK_ENABLE();	
//		__SYSTEM_GPIOD_CLK_ENABLE();
//#else
//        __SYSTEM_I2C3_CLK_ENABLE();
//#endif
//        i2c_init(&i2c_touchpad_handle);
    }
}


__RAM_CODE void hw_psram_io_init(bool wake_up)
{

    if (wake_up == false)
    {
        GPIO_InitTypeDef gpio_config;

        gpio_config.Pin = GPIO_PIN_12 | GPIO_PIN_13;
        gpio_config.Mode = GPIO_MODE_AF_PP;
        gpio_config.Pull = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_9;
        gpio_init(GPIOB, &gpio_config);

        gpio_config.Pin = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_5 | GPIO_PIN_6;
        gpio_config.Mode = GPIO_MODE_AF_PP;
        gpio_config.Pull = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_9;
        gpio_init(GPIOC, &gpio_config);

    }
    else
    {

    }

}

__RAM_CODE void hw_psram_init(bool wake_up)
{
    uint32_t reg_value;

#ifdef PSRAM_EXT_IO_CONTROLE
    hw_psram_io_init(wake_up);
#endif

    __SYSTEM_OSPI_CLK_SELECT_AUPLL();
    __SYSTEM_OSPI_CLK_ENABLE();
    __SYSTEM_AHBC_CLK_ENABLE();
    __CACHE_FLUSH(CACHE);
    __CACHE_WR_MODE_SET(CACHE, CACHE_WR_WRITE_THROUGH);
    __CACHE_ADDR_RANGEx_BANK_SET(CACHE, 0, 0 >> 16);
    __CACHE_ADDR_RANGEx_MASK_SET(CACHE, 0, 0x001F);
    __CACHE_ADDR_RANGEx_POL_SET(CACHE, 0, CACHE_POL_CACHABLE);
    __CACHE_ADDR_RANGEx_ENABLE(CACHE, 0);
    __CACHE_ENABLE(CACHE);

    if (wake_up == false) {
        /* setup PSRAM OSPI RESET pin */
        SYSTEM->OspiPadConfig.OSPI_FuncMux |= 0x00300000;
        SYSTEM->OspiOutEN &= (~(1<<10));
        SYSTEM->OspiData |= (1<<10);
        system_delay_us(200);  // tPU > 150us
        SYSTEM->OspiData &= (~(1<<10));
        system_delay_us(10);   // tRP > 1us
        SYSTEM->OspiData |= (1<<10);
        system_delay_us(600);  // tDPDp > 500us
        system_delay_us(300);  // tHSPU > 1ms, from power up to fully access
    }

#ifdef PSRAM_EXT_IO_CONTROLE

    //配置PSRAM控制为外部IO,需屏蔽内部的OSPI控制。
    SYSTEM->OspiPadConfig.OSPI_FuncMux = 0xffffffff;

#else
    /* configure OSPI pad to OSPI 4-line mode function */
    reg_value = SYSTEM->OspiPadConfig.OSPI_FuncMux;
    reg_value &= 0xfcf00ffc;
    reg_value |= 0x01055001;
    SYSTEM->OspiPadConfig.OSPI_FuncMux = reg_value;
#endif

    psram_init();
}
#endif

__RAM_CODE void hw_external_flash_init(bool wake_up)
{
    if (wake_up == false) {
        GPIO_InitTypeDef gpio_config;

        /* ========================================================== */
        /* =========  External Flash interface configuration ======== */
        /* ========================================================== */
        /* config GPIO for external flash */
        gpio_config.Pin = GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
        gpio_config.Mode = GPIO_MODE_AF_PP;
        gpio_config.Pull = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_7;
        gpio_init(GPIOD, &gpio_config);

        /* CS of external flash is controllerd by software */
        __SYSTEM_GPIOD_CLK_ENABLE();
        gpio_config.Pin = GPIO_PIN_1;
        gpio_config.Mode = GPIO_MODE_OUTPUT_PP;
        gpio_config.Pull = GPIO_PULLUP;
        gpio_config.Alternate = GPIO_FUNCTION_0;
        gpio_init(GPIOD, &gpio_config);

        /* config DMA1 for external flash */
        __SYSTEM_DMA1_CLK_ENABLE();
        dma_flash_handle.DMAx                       = DMA1;
        dma_flash_handle.Channel                    = DMA_Channel0;
        dma_flash_handle.Init.Data_Flow             = DMA_P2M_DMAC;
        dma_flash_handle.Init.Request_ID            = DMA1_REQUEST_ID_2;
        system_dmac_request_id_config(SPIMX8_1_RX, DMA1_REQUEST_ID_2);
        dma_flash_handle.Init.Source_Master_Sel     = DMA_AHB_MASTER_2;
        dma_flash_handle.Init.Desination_Master_Sel = DMA_AHB_MASTER_3;
        dma_flash_handle.Init.Source_Inc            = DMA_ADDR_INC_NO_CHANGE;
        dma_flash_handle.Init.Desination_Inc        = DMA_ADDR_INC_INC;
        dma_flash_handle.Init.Source_Width          = DMA_TRANSFER_WIDTH_32;
        dma_flash_handle.Init.Desination_Width      = DMA_TRANSFER_WIDTH_32;
        dma_flash_handle.Init.Source_Burst_Len      = DMA_BURST_LEN_4;
        dma_flash_handle.Init.Desination_Burst_Len  = DMA_BURST_LEN_4;
        dma_init(&dma_flash_handle);

        /* Initial SPIx8_1 for extern flash */
        __SYSTEM_SPI_MASTER1_X8_CLK_ENABLE();
        spi_flash_handle.SPIx                       = SPIMX8_1;
        spi_flash_handle.Init.Work_Mode             = SPI_WORK_MODE_3;
        spi_flash_handle.Init.Frame_Size            = SPI_FRAME_SIZE_8BIT;
        spi_flash_handle.Init.BaudRate_Prescaler    = 4;//2;
        spi_flash_handle.Init.TxFIFOEmpty_Threshold = 20;
        spi_flash_handle.Init.RxFIFOFull_Threshold  = 16;
        spi_master_init(&spi_flash_handle);
        __SPI_RX_SAMPLE_DLY(spi_flash_handle.SPIx, 2);
        __SPI_CS_Release();

        IC_W25Qxx_QuadConfig(true);

        NVIC_EnableIRQ(DMA1_IRQn);
        NVIC_EnableIRQ(SPIMX8_1_IRQn);
    }
    else {
        __SYSTEM_GPIOD_CLK_ENABLE();
        
        __SYSTEM_DMA1_CLK_ENABLE();
        system_dmac_request_id_config(SPIMX8_1_RX, DMA1_REQUEST_ID_2);
        dma_init(&dma_flash_handle);
        
        __SYSTEM_SPI_MASTER1_X8_CLK_ENABLE();
        spi_master_init(&spi_flash_handle);
        __SPI_RX_SAMPLE_DLY(spi_flash_handle.SPIx, 2);
        
        NVIC_EnableIRQ(DMA1_IRQn);
        NVIC_EnableIRQ(SPIMX8_1_IRQn);
    }
}


__RAM_CODE void hw_dsp_xip_flash_init(bool wake_up)
{
    uint32_t reg_value;
    
    /* init QSPI1 for DSP XIP flash */
    __SYSTEM_QSPI1_CLK_SELECT_AUPLL();
    __SYSTEM_QSPI1_CLK_ENABLE();
    /* configure OSPI pad to DSP XIP flash function */
    reg_value = SYSTEM->OspiPadConfig.OSPI_FuncMux;
    reg_value &= 0xc3fff033;
    reg_value |= 0x14000544;
    SYSTEM->OspiPadConfig.OSPI_FuncMux = reg_value;

    /* power on DSP flash */
    ool_write(0xfc, ool_read(0xfc) | 0x01);

    /* configure DSP XIP controller */
    flash_enable_quad(QSPI1);
    flash_init_controller(QSPI1, FLASH_RD_TYPE_QUAD_FAST, FLASH_WR_TYPE_SINGLE);
    flash_set_baudrate(QSPI1, QSPI_BAUDRATE_DIV_4);
}

__RAM_CODE void hw_dsp_restore(void)
{
    
}

__RAM_CODE __attribute__((noinline)) static void rise_qspi_clock(void)
{
    __SYSTEM_QSPI0_CLK_SELECT_AUPLL();
    __QSPI_DELAY_CS_START_SET(QSPI0, 4);
    __QSPI_DELAY_CS_END_SET(QSPI0, 4);
    __QSPI_DELAY_CS_DESSERT_SET(QSPI0, 8);
    __QSPI_READ_CAPTURE_DELAY_SET(QSPI0, 3);    // FLASH_ID_PUYA_P25Q32: 4 when div is 2
                                                // FLASH_ID_XMC_XM25LU32: 3 when div is 2
                                                // FLASH_ID_GIANTEC_GT25Q16A: 1 when div is 4
                                                // FLASH_ID_GIANTEC_GT25Q16A: 4 when div is 2
    system_delay_us(1000);
}

__RAM_CODE void hw_xip_flash_init(bool wake_up)
{

    System_XIPConfig_t xip_config;
    xip_config.CLK_SRC_SEL = XIP_CLK_SEL_SPLL;
    xip_config.DIV_SEL = QSPI_BAUDRATE_DIV_4;
    xip_config.RD_TYPE = FLASH_RD_TYPE_QUAD;
    xip_config.WR_TYPE = FLASH_WR_TYPE_SINGLE;
	system_xip_flash_init(&xip_config, wake_up);

}

__RAM_CODE void hw_gpio_save(void)
{
    gpio_state.PortA_PullEN     = SYSTEM->PortA_PullEN;
    gpio_state.PortB_PullEN     = SYSTEM->PortB_PullEN;
    gpio_state.PortC_PullEN     = SYSTEM->PortC_PullEN;
    gpio_state.PortD_PullEN     = SYSTEM->PortD_PullEN;
                                
    gpio_state.PortA_PullSelect = SYSTEM->PortA_PullSelect;
    gpio_state.PortB_PullSelect = SYSTEM->PortB_PullSelect;
    gpio_state.PortC_PullSelect = SYSTEM->PortC_PullSelect;
    gpio_state.PortD_PullSelect = SYSTEM->PortD_PullSelect;
                                                         
    gpio_state.PortA_DriveCfg   = SYSTEM->PortA_DriveCfg;
    gpio_state.PortB_DriveCfg   = SYSTEM->PortB_DriveCfg;
    gpio_state.PortC_DriveCfg   = SYSTEM->PortC_DriveCfg;
    gpio_state.PortD_DriveCfg   = SYSTEM->PortD_DriveCfg;
                                 
    gpio_state.PortA_L_FuncMux  = SYSTEM->PortA_L_FuncMux;
    gpio_state.PortA_H_FuncMux  = SYSTEM->PortA_H_FuncMux;
    gpio_state.PortB_L_FuncMux  = SYSTEM->PortB_L_FuncMux;
    gpio_state.PortB_H_FuncMux  = SYSTEM->PortB_H_FuncMux;
    gpio_state.PortC_L_FuncMux  = SYSTEM->PortC_L_FuncMux;
    gpio_state.PortC_H_FuncMux  = SYSTEM->PortC_H_FuncMux;
    gpio_state.PortD_L_FuncMux  = SYSTEM->PortD_L_FuncMux;
    gpio_state.PortD_H_FuncMux  = SYSTEM->PortD_H_FuncMux;
    
    gpio_state.QSPI_PullSelect  = SYSTEM->QspiPadConfig.QSPI_PullSelect;
    gpio_state.QSPI_PullEN      = SYSTEM->QspiPadConfig.QSPI_PullEN;
    gpio_state.OSPI_PullSelect  = SYSTEM->OspiPadConfig.OSPI_PullSelect;
    gpio_state.OSPI_PullEN      = SYSTEM->OspiPadConfig.OSPI_PullEN;
    
    __SYSTEM_GPIOA_CLK_ENABLE();
    __SYSTEM_GPIOB_CLK_ENABLE();
    __SYSTEM_GPIOC_CLK_ENABLE();
    __SYSTEM_GPIOD_CLK_ENABLE();
    
    gpio_state.GPIOA_OutputEN   = GPIOA->GPIO_OutputEN;
    gpio_state.GPIOA_OUT_DATA   = GPIOA->GPIO_OUT_DATA;
    gpio_state.GPIOA_EXTI_EN    = GPIOA->EXTI_EN;
    gpio_state.GPIOA_EXTI_INT_EN= GPIOA->EXTI_INT_EN;
    gpio_state.GPIOA_EXTI_TYPE  = GPIOA->EXTI_TYPE;
    gpio_state.GPIOB_OutputEN   = GPIOB->GPIO_OutputEN;
    gpio_state.GPIOB_OUT_DATA   = GPIOB->GPIO_OUT_DATA;
    gpio_state.GPIOB_EXTI_EN    = GPIOB->EXTI_EN;
    gpio_state.GPIOB_EXTI_INT_EN= GPIOB->EXTI_INT_EN;
    gpio_state.GPIOB_EXTI_TYPE  = GPIOB->EXTI_TYPE;
    gpio_state.GPIOC_OutputEN   = GPIOC->GPIO_OutputEN;
    gpio_state.GPIOC_OUT_DATA   = GPIOC->GPIO_OUT_DATA;
    gpio_state.GPIOC_EXTI_EN    = GPIOC->EXTI_EN;
    gpio_state.GPIOC_EXTI_INT_EN= GPIOC->EXTI_INT_EN;
    gpio_state.GPIOC_EXTI_TYPE  = GPIOC->EXTI_TYPE;
    gpio_state.GPIOD_OutputEN   = GPIOD->GPIO_OutputEN;
    gpio_state.GPIOD_OUT_DATA   = GPIOD->GPIO_OUT_DATA;
    gpio_state.GPIOD_EXTI_EN    = GPIOD->EXTI_EN;
    gpio_state.GPIOD_EXTI_INT_EN= GPIOD->EXTI_INT_EN;
    gpio_state.GPIOD_EXTI_TYPE  = GPIOD->EXTI_TYPE;
}

__RAM_CODE void hw_gpio_restore(void)
{
    SYSTEM->PortA_PullEN     = gpio_state.PortA_PullEN;
    SYSTEM->PortB_PullEN     = gpio_state.PortB_PullEN;
    SYSTEM->PortC_PullEN     = gpio_state.PortC_PullEN;
    SYSTEM->PortD_PullEN     = gpio_state.PortD_PullEN;

    SYSTEM->PortA_PullSelect = gpio_state.PortA_PullSelect;
    SYSTEM->PortB_PullSelect = gpio_state.PortB_PullSelect;
    SYSTEM->PortC_PullSelect = gpio_state.PortC_PullSelect;
    SYSTEM->PortD_PullSelect = gpio_state.PortD_PullSelect;

    SYSTEM->PortA_DriveCfg   = gpio_state.PortA_DriveCfg;
    SYSTEM->PortB_DriveCfg   = gpio_state.PortB_DriveCfg;
    SYSTEM->PortC_DriveCfg   = gpio_state.PortC_DriveCfg;
    SYSTEM->PortD_DriveCfg   = gpio_state.PortD_DriveCfg;

    SYSTEM->PortA_L_FuncMux  = gpio_state.PortA_L_FuncMux;
    SYSTEM->PortA_H_FuncMux  = gpio_state.PortA_H_FuncMux;
    SYSTEM->PortB_L_FuncMux  = gpio_state.PortB_L_FuncMux;
    SYSTEM->PortB_H_FuncMux  = gpio_state.PortB_H_FuncMux;
    SYSTEM->PortC_L_FuncMux  = gpio_state.PortC_L_FuncMux;
    SYSTEM->PortC_H_FuncMux  = gpio_state.PortC_H_FuncMux;
    SYSTEM->PortD_L_FuncMux  = gpio_state.PortD_L_FuncMux;
    SYSTEM->PortD_H_FuncMux  = gpio_state.PortD_H_FuncMux;

    SYSTEM->QspiPadConfig.QSPI_PullSelect   = gpio_state.QSPI_PullSelect;
    SYSTEM->QspiPadConfig.QSPI_PullEN       = gpio_state.QSPI_PullEN;
    SYSTEM->OspiPadConfig.OSPI_PullSelect   = gpio_state.OSPI_PullSelect;
    SYSTEM->OspiPadConfig.OSPI_PullEN       = gpio_state.OSPI_PullEN;

    __SYSTEM_GPIOA_CLK_ENABLE();
    __SYSTEM_GPIOB_CLK_ENABLE();
    __SYSTEM_GPIOC_CLK_ENABLE();
    __SYSTEM_GPIOD_CLK_ENABLE();

    GPIOA->GPIO_OutputEN     = gpio_state.GPIOA_OutputEN;
    GPIOA->GPIO_OUT_DATA     = gpio_state.GPIOA_OUT_DATA;
    GPIOA->EXTI_EN           = gpio_state.GPIOA_EXTI_EN;
    GPIOA->EXTI_INT_EN       = gpio_state.GPIOA_EXTI_INT_EN;
    GPIOA->EXTI_TYPE         = gpio_state.GPIOA_EXTI_TYPE;
    GPIOB->GPIO_OutputEN     = gpio_state.GPIOB_OutputEN;
    GPIOB->GPIO_OUT_DATA     = gpio_state.GPIOB_OUT_DATA;
    GPIOB->EXTI_EN           = gpio_state.GPIOB_EXTI_EN;
    GPIOB->EXTI_INT_EN       = gpio_state.GPIOB_EXTI_INT_EN;
    GPIOB->EXTI_TYPE         = gpio_state.GPIOB_EXTI_TYPE;
    GPIOC->GPIO_OutputEN     = gpio_state.GPIOC_OutputEN;
    GPIOC->GPIO_OUT_DATA     = gpio_state.GPIOC_OUT_DATA;
    GPIOC->EXTI_EN           = gpio_state.GPIOC_EXTI_EN;
    GPIOC->EXTI_INT_EN       = gpio_state.GPIOC_EXTI_INT_EN;
    GPIOC->EXTI_TYPE         = gpio_state.GPIOC_EXTI_TYPE;
    GPIOD->GPIO_OutputEN     = gpio_state.GPIOD_OutputEN;
    GPIOD->GPIO_OUT_DATA     = gpio_state.GPIOD_OUT_DATA;
    GPIOD->EXTI_EN           = gpio_state.GPIOD_EXTI_EN;
    GPIOD->EXTI_INT_EN       = gpio_state.GPIOD_EXTI_INT_EN;
    GPIOD->EXTI_TYPE         = gpio_state.GPIOD_EXTI_TYPE;
}

__RAM_CODE void hw_clock_init(void)
{
    System_ClkConfig_t sys_clk_cfg;

    sys_clk_cfg.SPLL_CFG.PLL_N = 8;
    sys_clk_cfg.SPLL_CFG.PLL_M = 0;
    sys_clk_cfg.SPLL_CFG.PowerEn = 1;
    sys_clk_cfg.MCU_Clock_Source = MCU_CLK_SEL_SPLL_CLK;
    sys_clk_cfg.SOC_DIV = 1;
    sys_clk_cfg.MCU_DIV = 1;
    sys_clk_cfg.APB0_DIV = 1;
    sys_clk_cfg.APB1_DIV = 1;
    sys_clk_cfg.APB2_DIV = 1;
	
	
	/* PLL clock = HSE_VALUE*N + (HSE_VALUE/65535)*M */
    /* AUPLL CLK Config */
    sys_clk_cfg.AUPLL_CFG.PowerEn = PLL_POWER_ENABLE;
    sys_clk_cfg.AUPLL_CFG.PLL_N = 8;
    sys_clk_cfg.AUPLL_CFG.PLL_K = 0;
    sys_clk_cfg.AUPLL_CFG.PLL_D = 0;

    System_SPLL_config(&sys_clk_cfg.SPLL_CFG, 1000);
		System_AUPLL_config(&sys_clk_cfg.AUPLL_CFG,200);
		
		



  
		
    System_MCU_clock_Config(&sys_clk_cfg);

    __SYSTEM_I2C_CLK_SELECT_SPLL();
    __SYSTEM_UART_CLK_SELECT_SPLL();
		      // 3. 在系统层面，选择AUPLL作为PSD_DAC的时钟源
    __SYSTEM_PSD_DAC_CLK_SELECT_AUPLL();
		__SYSTEM_PSD_DAC_CLK_ENABLE();
}
